package com.recommendation.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.lang.StringUtils;

import com.recommendation.domain.RecommendScope;
import com.recommendation.domain.SpecialItems;
import com.recommendation.taobao.TaobaoProxy;
import com.taobao.api.ApiException;
import com.taobao.api.domain.Item;
import com.taobao.api.response.ItemsListGetResponse;
import com.taobao.api.response.ItemsOnsaleGetResponse;

public class RecommendItemsProvider {
	
	static Logger _logger = Logger.getLogger(RecommendItemsProvider.class.getName());
	
	public static final RecommendItemsProvider INSTANCE = new RecommendItemsProvider();

	public List<Item> getItems(long userId, RecommendScope scope, List<Item> excludeItems, int num, String session, short version) throws Exception
	{
		switch(scope.getType())
		{
			case RecommendScope.TYPE_KEYWORD:
				return getItems2RecommendByKeyword(scope.getKeyword(), session, num, excludeItems);
			case RecommendScope.TYPE_CATEGORIES:
				return getItems2RecommendByCategories(scope.getSellerCids(), session, num, excludeItems);
			case RecommendScope.TYPE_SPECIFIED:
				return getSpecified2RecommendItems(scope.getItems(), session, num, excludeItems);
			default:
				return getItems2RecommendByKeyword(null, session, num, excludeItems);
		}
	}
	
	private List<Item> getItems2RecommendByKeyword(String keyword, String topSession, int num, List<Item> excludes)
	{
		_logger.info("keyword: " + keyword);
		try {
			ItemsOnsaleGetResponse itemsRsp = TaobaoProxy.getOldestOnSalesByKeyword(keyword, 200, topSession);
			if (itemsRsp.isSuccess())
			{
				List<Item> items = itemsRsp.getItems();
				if (items != null)
				{
					items = TaobaoService.removeAll(items, excludes);
					if (items.size() > num)
					{
						items = items.subList(0, num);
					}
					return items;
				}
				else
				{
					_logger.warning("items is null");
				}
			}
			else
			{
				_logger.log(Level.SEVERE, TaobaoProxy.getError(itemsRsp));
			}
		} catch (ApiException e) {
			_logger.log(Level.SEVERE, "", e);
		}
		return null;
	}
	
	private List<Item> getItems2RecommendByCategories(String sellerCids, String topSession, int num, List<Item> excludes)
	{
		try {
			ItemsOnsaleGetResponse itemsRsp = TaobaoProxy.getOldestOnSalesByCategories(sellerCids, 200, topSession);
			if (itemsRsp.isSuccess())
			{
				List<Item> items = itemsRsp.getItems();
				if (items != null)
				{
					items = TaobaoService.removeAll(items, excludes);
					if (items.size() > num)
					{
						items = items.subList(0, num);
					}
					return items;
				}
			}
			else
			{
				_logger.log(Level.SEVERE, TaobaoProxy.getError(itemsRsp));
			}
		} catch (ApiException e) {
			_logger.log(Level.SEVERE, "", e);
		}
		return null;
	}
	
	private List<Item> getSpecified2RecommendItems(String numIids, String session, int num, List<Item> excludes)
	{
		_logger.info("numIids: " + numIids);
		List<Item> items = new ArrayList<Item>();
		if (numIids != null)
		{
			String[] numIidArray = numIids.split(",");
			if (numIidArray != null && numIidArray.length > 0)
			{
				_logger.info("length: " + numIidArray.length);
				int pages = numIidArray.length / 20 + 1;
				_logger.info("pages: " + pages);
				for (int i = 0; i < pages; i++)
				{
					int from = i * 20;
					int to = Math.min((i + 1) * 20, numIidArray.length);
					String[] page = Arrays.copyOfRange(numIidArray, from, to);
					String partialNumIids = StringUtils.join(page, ",");
					_logger.info("page: " + partialNumIids);
					try {
						ItemsListGetResponse rsp = TaobaoProxy.getItems(partialNumIids, "num_iid,title,pic_url,price,delist_time,has_showcase", session);
						if (rsp.isSuccess())
						{
							List<Item> list = rsp.getItems();
							if (list != null)
							{
								for (Item it : list)
								{
									if (!it.getHasShowcase())
									{
										_logger.info("filtered out: " + it.getTitle());
										items.add(it);
									}
								}
							}
						}
						else
						{
							_logger.warning(TaobaoProxy.getError(rsp));
						}
					} catch (ApiException e) {
						_logger.log(Level.SEVERE, "", e);
					}
				}
				items = TaobaoService.removeAll(items, excludes);
				Collections.sort(items, new Comparator<Item>(){
					public int compare(Item o1, Item o2) {
						return o1.getDelistTime().compareTo(o2.getDelistTime());
					}
				});
				if (items.size() > num)
				{
					items = items.subList(0, num);
				}
			}
		}
		return items;
	}
	
	public List<Item> getMustItems(SpecialItems special, String session) throws Exception
	{
		if (special != null)
		{
			String mustItems = special.getMustItems();
			if (mustItems != null && mustItems.length() > 0)
			{
				TaobaoService service = new TaobaoService();
				String fields = "num_iid,title,pic_url,delist_time,has_showcase";
				List<Item> items = service.getItems(mustItems, fields, session);
				Collections.sort(items, new Comparator<Item>(){
					public int compare(Item o1, Item o2) {
						return o1.getDelistTime().compareTo(o2.getDelistTime());
					}
				});
				return items;
			}
		}
		return null;
	}
	
	public List<Item> getExcludeItems(SpecialItems special, String session) throws Exception
	{
		List<Item> excludedItems = null;
		if (special != null)
		{
			excludedItems = new ArrayList<Item>();
			TaobaoService service = new TaobaoService();
			String fields = "num_iid,title,pic_url,delist_time,has_showcase";
			String notItems = special.getNotItems();
			if (notItems != null && notItems.length() > 0)
			{
				List<Item> items = service.getItems(notItems, fields, session);
				excludedItems.addAll(items);
			}
			String notKeyword = special.getNotKeyword();
			if (notKeyword != null && notKeyword.length() > 0)
			{
				List<Item> items = service.getOnsaleItems(notKeyword, fields, null, session);
				excludedItems.addAll(items);
			}
		}
		return excludedItems;
	}
}
